
#include "image_det.h"

// 1.取ROI做一个仿射变换
// 2.试一下用ROI做像素值阈值  做阶跃判断  

std::string getCurrentTimeString() {
    auto t = std::time(nullptr);
    struct tm tm;
    localtime_s(&tm, &t); // 使用 localtime_s 代替 localtime
    std::ostringstream oss;
    oss << std::put_time(&tm, "%Y%m%d_%H%M%S");
    return oss.str();
}

Mat ImageDet::processImage(const Mat& img, const std::vector<Point>& pointsA, const std::vector<Point>& pointsB, const Rect& cropRegion) {

    //// 参数校验
    //if (pointsA.size() != 4) {
    //    throw std::invalid_argument("Exactly 4 points are required.");
    //}
    //if (cropRegion.x < 0 || cropRegion.y < 0 ||
    //    cropRegion.x + cropRegion.width > img.cols ||
    //    cropRegion.y + cropRegion.height > img.rows) {
    //    throw std::out_of_range("Crop region is out of bounds.");
    //}

    Mat zeroImage = Mat::zeros(img.size(), CV_8UC1);
    Mat mask1 = Mat::zeros(img.size(), CV_8UC1);

    std::vector<std::vector<Point>> contoursA = { pointsA };
    drawContours(mask1, contoursA, -1, Scalar(255), FILLED);
    img.copyTo(zeroImage, mask1);
    Mat croppedImage = zeroImage(cropRegion);
    Mat mask2 = Mat::zeros(croppedImage.size(), CV_8UC1);
    // 填充多边形区域为白色（255），这样就创建了一个仅有多边形部分透明而其余地方不透明的蒙版
    fillConvexPoly(mask2, &pointsB[0], static_cast<int>(pointsB.size()), Scalar(255));

    // 应用此蒙版到原始图片上，使得只有被选中的多边形区域保留原有色彩，其他位置变为黑色背景
    bitwise_and(croppedImage, croppedImage, croppedImage, mask2);

    // 或者直接将多边形内像素置零
    croppedImage.setTo(Scalar(0, 0, 0), mask2);


    return croppedImage;
}

bool ImageDet::detResult(const cv::Mat& image,int segmentation,int par2)
{
    // 创建掩膜，筛选大于0的像素
    cv::Mat mask_than_zero = image > 0;

    // 获取大于0的像素值
    cv::Mat values = image.clone();
    values.setTo(0, ~mask_than_zero);  // 将掩膜中值为0的地方置为0

    // 计算大于0的像素值的均值
    double mean_value = cv::mean(values, mask_than_zero)[0];  // 使用掩膜计算均值

    int rows = image.rows;
    int cols = image.cols;

    std::vector<float> row_means(rows, 0);
    int count_left_part = 0;  // 记录x < 400部分符合条件的行数
    int count_right_part = 0; // 记录x >= 400部分符合条件的行数

    int firstZeroX = -1;
    for (int x = 0; x < image.cols; x++) {
        if (image.at<uchar>(0, x) == 0) {
            firstZeroX = x;
            break;
        }
    }


    // 遍历每一行，计算每行的均值
    for (int i = 0; i < rows; ++i)
    {
        float sum_left = 0, sum_right = 0;
        int valid_pixel_count_left = 0, valid_pixel_count_right = 0;

        
        // 分别处理x小于400的部分和x大于等于400的部分
        for (int j = 0; j < cols; ++j) {
            if (image.at<uchar>(i, j) > 0) {
                if (j < segmentation) {
                    sum_left += image.at<uchar>(i, j);
                    ++valid_pixel_count_left;
                }
                else {
                    sum_right += image.at<uchar>(i, j);
                    ++valid_pixel_count_right;
                }
            }
        }

        // 计算左右部分的均值
        float mean_left = (valid_pixel_count_left > 0) ? sum_left / valid_pixel_count_left : 0;
        float mean_right = (valid_pixel_count_right > 0) ? sum_right / valid_pixel_count_right : 0;

        // 输出每一行的均值
        //std::cout << "Row " << i << " left part mean: " << mean_left << ", right part mean: " << mean_right << std::endl;

        // 判断左侧部分是否符合条件

        if (/*(mean_left > mean_value * 1.2)&&*/ (mean_left >par2)) {
            ++count_left_part;
        }

        // 判断右侧部分是否符合条件
        if (/*(mean_right > mean_value * 1.2) &&*/(mean_right > par2)) {
            ++count_right_part;
        }

        // 如果左侧部分符合条件5次，返回 false
        if (count_left_part >= 5) {
            return false;
        }

        // 如果右侧部分符合条件5次，返回 false
        if (count_right_part >= 5) {
            return false;
        }
    }

    // 如果循环结束，没有任何部分满足条件，返回 true
    return true;
}


